﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using YAPL.Language.Core.Types;

namespace YAPL.Language.Compiler.CodeGen.ReflectionEmitGenerator.AstGen.Helpers {
	public static class ILGeneratorConstantExtensions {
		private static readonly ConstructorInfo _stringConstructor;
		private static readonly ConstructorInfo _intConstructor;
		private static readonly ConstructorInfo _floatConstructor;
		private static readonly ConstructorInfo _booleanConstructor;
		static ILGeneratorConstantExtensions() {
			_stringConstructor = typeof(YAPLString).GetConstructor(
				BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null,
				new[] { typeof(string) }, null);
			_intConstructor = typeof(YAPLInt).GetConstructor(
				BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null,
				new[] { typeof(int) }, null);
			_floatConstructor = typeof(YAPLFloat).GetConstructor(
				BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null,
				new[] { typeof(double) }, null);
			_booleanConstructor = typeof(YAPLBoolean).GetConstructor(
				BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null,
				new[] { typeof(bool) }, null);
		}
		public static void EmitCreateSimpleType(this ILGenerator ilGen, Type yaplType, object value) {
			if (yaplType == typeof(YAPLString)) {
				ilGen.Emit(OpCodes.Ldstr, (string)value);
				ilGen.Emit(OpCodes.Newobj, _stringConstructor);
			} else if (yaplType == typeof(YAPLInt)) {
				ilGen.Emit(OpCodes.Ldc_I4, (int)value);
				ilGen.Emit(OpCodes.Newobj, _intConstructor);
			} else if (yaplType == typeof(YAPLFloat)) {
				ilGen.Emit(OpCodes.Ldc_R8, (double)value);
				ilGen.Emit(OpCodes.Newobj, _floatConstructor);
			} else if (yaplType == typeof(YAPLBoolean)) {
				ilGen.Emit((bool)value ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0);
				ilGen.Emit(OpCodes.Newobj, _booleanConstructor);
			}
		}
	}
}
